from PyQt6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                           QPushButton, QLabel, QLineEdit, QCalendarWidget,
                           QStackedWidget, QMessageBox, QFrame, QTableWidget, QTableWidgetItem, QDialog, QGroupBox, QCheckBox)
from PyQt6.QtCore import Qt, QDate
from PyQt6.QtGui import QFont, QIcon, QPainter
import sys
from datetime import datetime
from period_tracker.core import User, PeriodPredictor, DataManager
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from datetime import timedelta
from matplotlib.dates import DateFormatter
from matplotlib.ticker import MultipleLocator, MaxNLocator

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.data_manager = DataManager()
        self.current_user = None
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle('经期跟踪助手')
        self.setMinimumSize(800, 600)
        
        # 创建堆叠窗口用于切换不同页面
        self.stacked_widget = QStackedWidget()
        self.setCentralWidget(self.stacked_widget)
        
        # 创建登录和注册页面
        self.login_page = LoginPage(self)
        self.register_page = RegisterPage(self)
        self.main_page = MainPage(self)
        
        # 添加页面到堆叠窗口
        self.stacked_widget.addWidget(self.login_page)
        self.stacked_widget.addWidget(self.register_page)
        self.stacked_widget.addWidget(self.main_page)
        
        # 设置样式
        self.setStyleSheet("""
            QMainWindow {
                background-color: #f0f2f5;
            }
            QPushButton {
                background-color: #1877f2;
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 6px;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #166fe5;
            }
            QLineEdit {
                padding: 10px;
                border: 1px solid #dddfe2;
                border-radius: 6px;
                font-size: 14px;
            }
            QLabel {
                font-size: 14px;
                color: #1c1e21;
            }
        """)

class LoginPage(QWidget):
    def __init__(self, main_window):
        super().__init__()
        self.main_window = main_window
        self.init_ui()
        
    def init_ui(self):
        layout = QVBoxLayout()
        layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 标题
        title = QLabel('经期跟踪助手')
        title.setFont(QFont('Arial', 24, QFont.Weight.Bold))
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 登录表单
        form = QFrame()
        form.setStyleSheet("""
            QFrame {
                background-color: white;
                border-radius: 8px;
                padding: 20px;
            }
        """)
        form_layout = QVBoxLayout()
        
        self.username_input = QLineEdit()
        self.username_input.setPlaceholderText('用户名')
        self.password_input = QLineEdit()
        self.password_input.setPlaceholderText('密码')
        self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
        
        login_btn = QPushButton('登录')
        login_btn.clicked.connect(self.login)
        
        register_btn = QPushButton('注册新账号')
        register_btn.setStyleSheet("""
            background-color: #42b72a;
        """)
        register_btn.clicked.connect(self.show_register)
        
        form_layout.addWidget(self.username_input)
        form_layout.addWidget(self.password_input)
        form_layout.addWidget(login_btn)
        form_layout.addWidget(register_btn)
        
        form.setLayout(form_layout)
        layout.addWidget(form)
        
        self.setLayout(layout)
    
    def login(self):
        username = self.username_input.text()
        password = self.password_input.text()
        
        user = self.main_window.data_manager.load_user(username, password)
        if user:
            self.main_window.current_user = user
            self.main_window.main_page.update_user_info()
            self.main_window.stacked_widget.setCurrentIndex(2)
        else:
            QMessageBox.warning(self, '登录失败', '用户名或密码错误')
    
    def show_register(self):
        self.main_window.stacked_widget.setCurrentIndex(1)

class RegisterPage(QWidget):
    def __init__(self, main_window):
        super().__init__()
        self.main_window = main_window
        self.init_ui()
        
    def init_ui(self):
        layout = QVBoxLayout()
        layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 标题
        title = QLabel('注册新账号')
        title.setFont(QFont('Arial', 20, QFont.Weight.Bold))
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        # 注册表单
        form = QFrame()
        form.setStyleSheet("""
            QFrame {
                background-color: white;
                border-radius: 8px;
                padding: 20px;
                max-width: 400px;
            }
        """)
        
        form_layout = QVBoxLayout()
        
        # 输入框
        self.username = QLineEdit()
        self.username.setPlaceholderText('用户名')
        
        self.password = QLineEdit()
        self.password.setPlaceholderText('密码')
        self.password.setEchoMode(QLineEdit.EchoMode.Password)
        
        self.confirm_password = QLineEdit()
        self.confirm_password.setPlaceholderText('确认密码')
        self.confirm_password.setEchoMode(QLineEdit.EchoMode.Password)
        
        self.age = QLineEdit()
        self.age.setPlaceholderText('年龄')
        
        self.cycle_length = QLineEdit()
        self.cycle_length.setPlaceholderText('平均经期长度（天）')
        
        self.phone = QLineEdit()
        self.phone.setPlaceholderText('手机号码（可选）')
        
        self.wechat = QLineEdit()
        self.wechat.setPlaceholderText('微信号（可选）')
        
        # 按钮
        register_btn = QPushButton('注册')
        register_btn.clicked.connect(self.register)
        
        back_btn = QPushButton('返回登录')
        back_btn.setStyleSheet("""
            background-color: #42b72a;
        """)
        back_btn.clicked.connect(self.back_to_login)
        
        # 添加所有组件到布局
        form_layout.addWidget(self.username)
        form_layout.addWidget(self.password)
        form_layout.addWidget(self.confirm_password)
        form_layout.addWidget(self.age)
        form_layout.addWidget(self.cycle_length)
        form_layout.addWidget(self.phone)
        form_layout.addWidget(self.wechat)
        form_layout.addWidget(register_btn)
        form_layout.addWidget(back_btn)
        
        form.setLayout(form_layout)
        
        layout.addWidget(title)
        layout.addWidget(form)
        self.setLayout(layout)
    
    def register(self):
        # 获取输入数据
        username = self.username.text()
        password = self.password.text()
        confirm_pwd = self.confirm_password.text()
        
        try:
            age = int(self.age.text())
            cycle_length = int(self.cycle_length.text())
        except ValueError:
            QMessageBox.warning(self, '错误', '年龄和经期长度必须是数字')
            return
            
        # 验证输入
        if not all([username, password, confirm_pwd]):
            QMessageBox.warning(self, '错误', '请填写所有必填字段')
            return
            
        if password != confirm_pwd:
            QMessageBox.warning(self, '错误', '两次输入的密码不一致')
            return
            
        if self.main_window.data_manager.user_exists(username):
            QMessageBox.warning(self, '错误', '用户名已存在')
            return
            
        # 创建新用户
        user = User()
        user.create_user(
            username=username,
            password=password,
            age=age,
            avg_cycle_length=cycle_length,
            phone_number=self.phone.text(),
            wechat_id=self.wechat.text()
        )
        
        # 保存用户数据
        self.main_window.data_manager.save_user(user)
        QMessageBox.information(self, '成功', '注册成功！请登录')
        self.back_to_login()
        
    def back_to_login(self):
        self.main_window.stacked_widget.setCurrentIndex(0)

class MainPage(QWidget):
    def __init__(self, main_window):
        super().__init__()
        self.main_window = main_window
        self.init_ui()
        
    def init_ui(self):
        main_layout = QVBoxLayout()
        
        # 顶部工具栏
        toolbar = QFrame()
        toolbar.setStyleSheet("""
            QFrame {
                background-color: white;
                border-radius: 8px;
                margin: 10px;
            }
        """)
        toolbar_layout = QHBoxLayout()
        
        # 添加功能按钮
        add_record_btn = QPushButton('添加经期记录')
        add_record_btn.clicked.connect(self.add_period_record)
        
        history_btn = QPushButton('历史记录')
        history_btn.clicked.connect(self.show_history)
        
        settings_btn = QPushButton('提醒设置')
        settings_btn.clicked.connect(self.show_settings)
        
        logout_btn = QPushButton('退出登录')
        logout_btn.setStyleSheet("""
            background-color: #dc3545;
        """)
        logout_btn.clicked.connect(self.logout)
        
        toolbar_layout.addWidget(add_record_btn)
        toolbar_layout.addWidget(history_btn)
        toolbar_layout.addWidget(settings_btn)
        toolbar_layout.addStretch()
        toolbar_layout.addWidget(logout_btn)
        
        toolbar.setLayout(toolbar_layout)
        main_layout.addWidget(toolbar)
        
        # 主要内容区域
        content_layout = QHBoxLayout()
        
        # 左侧面板（日历）
        left_panel = QFrame()
        left_panel.setStyleSheet("""
            QFrame {
                background-color: white;
                border-radius: 8px;
                margin: 10px;
            }
        """)
        left_layout = QVBoxLayout()
        
        self.calendar = QCalendarWidget()
        self.calendar.clicked.connect(self.date_selected)
        
        left_layout.addWidget(self.calendar)
        left_panel.setLayout(left_layout)
        
        # 右侧面板（图表和预测）
        right_panel = QFrame()
        right_panel.setStyleSheet("""
            QFrame {
                background-color: white;
                border-radius: 8px;
                margin: 10px;
            }
        """)
        right_layout = QVBoxLayout()
        
        # 创建matplotlib图表（解决中文显示问题）
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
        plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
        
        self.figure = Figure(figsize=(6, 4))
        self.canvas = FigureCanvas(self.figure)
        self.ax = self.figure.add_subplot(111)
        self.ax.set_title("经期周期变化趋势")
        self.ax.set_xlabel("日期")
        self.ax.set_ylabel("周期长度（天）")
        
        self.prediction_label = QLabel()
        self.prediction_label.setWordWrap(True)
        
        right_layout.addWidget(self.canvas)
        right_layout.addWidget(QLabel('预测信息'))
        right_layout.addWidget(self.prediction_label)
        right_panel.setLayout(right_layout)
        
        # 添加到内容布局
        content_layout.addWidget(left_panel, 2)
        content_layout.addWidget(right_panel, 1)
        
        # 添加内容区域到主布局
        main_layout.addLayout(content_layout)
        
        self.setLayout(main_layout)
    
    def update_chart(self):
        if not self.main_window.current_user.period_records:
            return
            
        # 获取周期数据
        dates = []
        intervals = []
        
        records = sorted(self.main_window.current_user.period_records,
                        key=lambda x: datetime.strptime(x['start_date'], '%Y-%m-%d'))
                        
        for i in range(1, len(records)):
            current_date = datetime.strptime(records[i]['start_date'], '%Y-%m-%d')
            prev_date = datetime.strptime(records[i-1]['start_date'], '%Y-%m-%d')
            interval = (current_date - prev_date).days
            
            dates.append(current_date)
            intervals.append(interval)
        
        # 清除旧图
        self.ax.clear()
        
        # 绘制新图
        if dates:
            # 绘制折线图
            self.ax.plot(dates, intervals, 'b-o', linewidth=2, markersize=8)
            
            # 设置标题和标签
            self.ax.set_title("经期周期变化趋势", fontsize=12, pad=15)
            self.ax.set_xlabel("日期", fontsize=10, labelpad=10)
            self.ax.set_ylabel("周期长度（天）", fontsize=10, labelpad=10)
            
            # 设置网格
            self.ax.grid(True, linestyle='--', alpha=0.7)
            
            # 设置y轴范围和刻度
            min_interval = min(intervals) if intervals else 20
            max_interval = max(intervals) if intervals else 40
            y_margin = 5  # 上下留白
            self.ax.set_ylim(max(0, min_interval - y_margin), max_interval + y_margin)
            
            # 设置y轴刻度为整数
            self.ax.yaxis.set_major_locator(plt.MultipleLocator(5))  # 主刻度为5的倍数
            self.ax.yaxis.set_minor_locator(plt.MultipleLocator(1))  # 次刻度为1
            
            # 格式化x轴日期显示
            self.ax.xaxis.set_major_formatter(plt.DateFormatter('%Y-%m-%d'))
            
            # 自动旋转日期标签
            plt.setp(self.ax.get_xticklabels(), rotation=45, ha='right')
            
            # 设置合适的日期间隔
            if len(dates) > 6:
                self.ax.xaxis.set_major_locator(plt.MaxNLocator(6))  # 最多显示6个日期
            
            # 添加数据点标签
            for x, y in zip(dates, intervals):
                self.ax.annotate(f'{y}天', 
                               (x, y),
                               xytext=(0, 5),
                               textcoords='offset points',
                               ha='center',
                               va='bottom')
            
            # 调整布局，确保标签不被截断
            self.figure.tight_layout()
            
            # 刷新画布
            self.canvas.draw()
    
    def update_user_info(self):
        if self.main_window.current_user:
            predictor = PeriodPredictor(self.main_window.current_user)
            next_period = predictor.predict_next_period()
            
            if next_period:
                self.prediction_label.setText(
                    f'下次经期预计开始时间：\n{next_period.strftime("%Y-%m-%d")}\n\n'
                    f'提醒日期：\n' + 
                    '\n'.join([d.strftime('%Y-%m-%d') for d in predictor.get_reminder_dates()])
                )
            else:
                self.prediction_label.setText('暂无足够数据进行预测')
    
    def date_selected(self, date):
        self.selected_date = date
    
    def add_period_record(self):
        if hasattr(self, 'selected_date'):
            self.main_window.current_user.add_period_record(
                datetime.combine(self.selected_date.toPyDate(), datetime.min.time())
            )
            self.main_window.data_manager.save_user(self.main_window.current_user)
            self.update_user_info()
            self.update_chart()
            QMessageBox.information(self, '成功', '经期记录已添加')
        else:
            QMessageBox.warning(self, '提示', '请先选择日期')
    
    def show_history(self):
        dialog = HistoryDialog(self.main_window.current_user, self)
        dialog.exec()
    
    def show_settings(self):
        dialog = SettingsDialog(self.main_window.current_user, self)
        dialog.exec()
        
    def logout(self):
        reply = QMessageBox.question(self, '确认', '确定要退出登录吗？',
                                   QMessageBox.StandardButton.Yes | 
                                   QMessageBox.StandardButton.No)
        if reply == QMessageBox.StandardButton.Yes:
            self.main_window.current_user = None
            self.main_window.stacked_widget.setCurrentIndex(0)

class HistoryDialog(QDialog):
    def __init__(self, user, parent=None):
        super().__init__(parent)
        self.user = user
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle('经期历史记录')
        self.setMinimumSize(400, 500)
        
        layout = QVBoxLayout()
        
        # 创建表格
        self.table = QTableWidget()
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(['日期', '操作'])
        
        # 加载数据
        records = sorted(self.user.period_records,
                        key=lambda x: datetime.strptime(x['start_date'], '%Y-%m-%d'),
                        reverse=True)
        
        self.table.setRowCount(len(records))
        for i, record in enumerate(records):
            date_item = QTableWidgetItem(record['start_date'])
            self.table.setItem(i, 0, date_item)
            
            delete_btn = QPushButton('删除')
            delete_btn.clicked.connect(lambda checked, row=i: self.delete_record(row))
            self.table.setCellWidget(i, 1, delete_btn)
        
        self.table.resizeColumnsToContents()
        layout.addWidget(self.table)
        
        self.setLayout(layout)
    
    def delete_record(self, row):
        date = self.table.item(row, 0).text()
        reply = QMessageBox.question(self, '确认',
                                   f'确定要删除 {date} 的记录吗？',
                                   QMessageBox.StandardButton.Yes | 
                                   QMessageBox.StandardButton.No)
        
        if reply == QMessageBox.StandardButton.Yes:
            self.user.period_records = [
                r for r in self.user.period_records
                if r['start_date'] != date
            ]
            self.table.removeRow(row)
            self.parent().main_window.data_manager.save_user(self.user)
            self.parent().update_chart()
            self.parent().update_user_info()

class SettingsDialog(QDialog):
    def __init__(self, user, parent=None):
        super().__init__(parent)
        self.user = user
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle('提醒设置')
        self.setMinimumSize(300, 200)
        
        layout = QVBoxLayout()
        
        # 微信提醒设置
        wechat_group = QGroupBox('微信提醒')
        wechat_layout = QVBoxLayout()
        
        self.wechat_enable = QCheckBox('启用微信提醒')
        self.wechat_id = QLineEdit(self.user.wechat_id or '')
        self.wechat_id.setPlaceholderText('微信号')
        
        wechat_layout.addWidget(self.wechat_enable)
        wechat_layout.addWidget(self.wechat_id)
        wechat_group.setLayout(wechat_layout)
        
        # 短信提醒设置
        sms_group = QGroupBox('短信提醒')
        sms_layout = QVBoxLayout()
        
        self.sms_enable = QCheckBox('启用短信提醒')
        self.phone = QLineEdit(self.user.phone_number or '')
        self.phone.setPlaceholderText('手机号码')
        
        sms_layout.addWidget(self.sms_enable)
        sms_layout.addWidget(self.phone)
        sms_group.setLayout(sms_layout)
        
        # 保存按钮
        save_btn = QPushButton('保存设置')
        save_btn.clicked.connect(self.save_settings)
        
        layout.addWidget(wechat_group)
        layout.addWidget(sms_group)
        layout.addWidget(save_btn)
        
        self.setLayout(layout)
    
    def save_settings(self):
        self.user.wechat_id = self.wechat_id.text()
        self.user.phone_number = self.phone.text()
        self.parent().main_window.data_manager.save_user(self.user)
        QMessageBox.information(self, '成功', '设置已保存')
        self.accept()